package org.fhm.zdte.server.cmd;

import org.fhm.substrate.annotation.BeanInitial;
import org.fhm.substrate.annotation.Component;
import org.fhm.substrate.service.LoggerHandler;
import org.fhm.substrate.standard.ILogger;
import org.fhm.zdte.common.constant.protocol.PacketType;
import org.fhm.zdte.common.constant.protocol.ResponseMessageType;
import org.fhm.zdte.common.constant.subcmd.ConnectCmd;
import org.fhm.zdte.common.pojo.Address;

import java.util.Objects;

/**
 * Connect command processor.
 *
 * @author 谭波
 * @since 2023/11/23
 */
@Component("CONNECT")
public class ConnectServerCmd extends AbstractServerCmd {

    private final ILogger logger = LoggerHandler.getLogger(ConnectServerCmd.class);

    @BeanInitial
    private void beanInitial() {
        subPacketDataDealMap.get(PacketType.CONNECT.getName())
                .putConsumer(
                        ConnectCmd.START_CONNECT,
                        (address, message) -> {
                            String from = message.getFrom();
                            String target = message.getTo();
                            Address toAddress;
                            if (Objects.nonNull((toAddress = onlineUserContainer.get(target)))) {
                                logger.info("连接方地址：" + toAddress + " 被连接方地址：" + address);
                                sendDealTask.getTaskAndSubmit(
                                        abstractMessageWrappers
                                                .getMessageByPacketType(
                                                        PacketType.CONNECT,
                                                        ConnectCmd.INQUIRIES,
                                                        from, "", message.getMessageNumber(),
                                                        null, address, toAddress,
                                                        message.getSecretKey()),
                                        toAddress
                                );
                            } else {
                                sendDealTask.getTaskAndSubmit(
                                        abstractMessageWrappers
                                                .getFailAckMessageByPacketType(
                                                        PacketType.CONNECT,
                                                        ResponseMessageType.USER_NO_ONLINE,
                                                        ConnectCmd.START_CONNECT,
                                                        target,
                                                        "",
                                                        null,
                                                        message.getMessageNumber()
                                                ),
                                        address
                                );
                            }
                        }
                )
                .putConsumer(
                        ConnectCmd.INQUIRIES,
                        (address, message) -> {
                            Address toAddress = message.getToAddress();
                            if (abstractMessageMonitor.isFailMessage(message)) {
                                sendDealTask.getTaskAndSubmit(message, toAddress);
                            } else {
                                sendDealTask.getTaskAndSubmit(
                                        abstractMessageWrappers.getAckMessageByPacketType(
                                                PacketType.CONNECT,
                                                ConnectCmd.START_CONNECT,
                                                message.getFrom(),
                                                "",
                                                address,
                                                toAddress,
                                                message.getMessageNumber()
                                        ),
                                        toAddress
                                );
                            }
                        }
                ).putConsumer(
                        ConnectCmd.CONNECT,
                        (address, message) -> {
                            String target = message.getTo();
                            Address toAddress;
                            if (Objects.nonNull((toAddress = onlineUserContainer.get(target)))) {
                                logger.info("notify connected start two-step connection");
                                sendDealTask.getTaskAndSubmit(
                                        abstractMessageWrappers.getMessageByPacketType(
                                                PacketType.CONNECT,
                                                ConnectCmd.CONNECT,
                                                message.getFrom(),
                                                "",
                                                message.getMessageNumber(),
                                                null,
                                                address,
                                                null,
                                                null
                                        ),
                                        toAddress
                                );
                            } else {
                                logger.info("fail to start two-step connection");
                                sendDealTask.getTaskAndSubmit(
                                        abstractMessageWrappers
                                                .getFailAckMessageByPacketType(
                                                        PacketType.CONNECT,
                                                        ResponseMessageType.USER_NO_ONLINE,
                                                        ConnectCmd.CONNECT,
                                                        target,
                                                        "",
                                                        null,
                                                        message.getMessageNumber()
                                                ),
                                        address
                                );
                            }
                        }
                );
    }


}
